﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Systemet.Domain;
using System.Data.SqlClient;

namespace Systemet.Technical
{
    /// <summary>
    /// Hanterar connections för produktrelaterade utsökningar.
    /// Hämtar, sparar, skapar och uppdaterar produkter.
    /// </summary>
    class ProduktConnection
    {
        private LinqToSQLDataContext database;
        private bool successfull;
        private string pass = AccessController.Instance.Connection;

        //Validerar ett produktobjekt. Beroende på isNew så antingen skapar eller uppdaterar 
        //man databasens objekt som stämmer överens med produktObjektet
        public bool validateProdukt(Produktregister produktObject, bool isNew)
        {
            try
            {
                pass = AccessController.Instance.Connection;
                database = new LinqToSQLDataContext(pass);

                var nyProdukt = from Produktregister in database.Produktregisters
                                where Produktregister.produkt == produktObject.produkt
                                select Produktregister.produkt;

                if (!nyProdukt.Contains(produktObject.produkt) && isNew == true)
                {
                    successfull = Produktregistrering(produktObject);
                }
                else if (nyProdukt.Contains(produktObject.produkt) && isNew == false)
                {
                    successfull = UpdateProduktregister(produktObject);
                }

                database.Connection.Close();
                return successfull;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return false;
            }
        }

        //Skapar ny produkt i produktregistret
        private bool Produktregistrering(Produktregister produktObject)
        {
            try
            {
                //List<Domain.ProduktGrupp> idn = getGruppID(produktObject);
                //List<Domain.ProduktKategori> kidn = getKategoriID(produktObject);

                //Produktregister nyProdukt = produktObject;

                //Produktregister nyProdukt = new Produktregister
                //{
                //    produktID = produktObject.ProduktID,
                //    produkt = produktObject.ProduktNamn,
                //    andratDatum = produktObject.Datum,
                //    produktGruppID = idn[0].ProduktgruppID,
                //    signatur = produktObject.Signerad,
                //    produktKategoriID = kidn[0].ProduktkategoriID,
                //    avdelningsnamn = produktObject.Produktionsomrade

                //};

                database.Produktregisters.InsertOnSubmit(produktObject);
                database.SubmitChanges();

                database.Connection.Close();
                return true;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return false;
            }
        }

        //Skapar ny produkt
        public bool ProduktregistreringFromFile(Produkt produktObject)
        {
            try
            {
                List<Domain.ProduktKategori> kidn = getKategoriID(produktObject);
                Produktregister nyProdukt = new Produktregister
                {
                    produktID = produktObject.ProduktID,
                    produkt = produktObject.ProduktNamn,
                    andratDatum = produktObject.Datum,
                    produktGruppID = produktObject.ProduktGruppID,
                    signatur = produktObject.Signerad,
                    produktKategoriID = kidn[0].ProduktkategoriID,
                    avdelningsnamn = produktObject.Produktionsomrade

                };

                database.Produktregisters.InsertOnSubmit(nyProdukt);
                database.SubmitChanges();

                database.Connection.Close();
                return true;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return false;
            }
        }

        //Returnerar produktgrupper som stämmer överens med produktobjeketets produktgrupp
        private IEnumerable<Produktgrupp> getGruppID(Produktregister produktObject)
        {
            try
            {
                database = new LinqToSQLDataContext(pass);
                IEnumerable<Produktgrupp> prodGrupplista = from Produktgrupp in database.Produktgrupps
                                                           where Produktgrupp.produktGruppNamn == produktObject.Produktgrupp.produktGruppNamn
                                                           select Produktgrupp;

                //List<Domain.ProduktGrupp> prodlista = prodGruppID.AsEnumerable()
                //  .Select(pr => new Domain.ProduktGrupp
                //  {
                //      ProduktgruppID = pr.produktGruppID
                //  }).ToList();

                database.Connection.Close();
                return prodGrupplista;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return null;
            }
        }

        //Returnerar lista med produktkategorier som stämmer överens med produktobjektets prodKategori
        private List<Domain.ProduktKategori> getKategoriID(Produkt produktObject)
        {
            try
            {
                database = new LinqToSQLDataContext(pass);
                var prodKategID = from Produktkategori in database.Produktkategoris
                                  where Produktkategori.produktKategoriNamn == produktObject.ProduktKategori
                                  select new { Produktkategori.produktKategoriID };

                List<Domain.ProduktKategori> prodlista = prodKategID.AsEnumerable()
                  .Select(pr => new Domain.ProduktKategori
                  {
                      ProduktkategoriID = pr.produktKategoriID
                  }).ToList();

                database.Connection.Close();
                return prodlista;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return null;
            }
        }

        //Returnerar alla produktgrupper
        public List<Produktgrupp> RetrieveProductGroups()
        {
            try
            {
                database = new LinqToSQLDataContext(pass);
                var prodgrupp = from Produktgrupp in database.Produktgrupps
                                select Produktgrupp;

                List<Produktgrupp> prodgrupper = prodgrupp.AsEnumerable()
                    .Select(pG => new Produktgrupp
                    {
                        produktGruppNamn = pG.produktGruppNamn,
                        produktGruppID = pG.produktGruppID,
                        andratDatum = pG.andratDatum,
                        signatur = pG.signatur
                    }).ToList();

                database.Connection.Close();
                return prodgrupper;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return null;
            }
        }

        //Uppdaterar produktregistrets produktobjekt som stämmer överens med produktobjektet
        private bool UpdateProduktregister(Produktregister produktObject)
        {
            Produktregister uppdateraProdukt = database.Produktregisters.Single(p => p.produkt == produktObject.produkt);
            try
            {
                //List<Domain.ProduktGrupp> gruppidn = getGruppID(produktObject);
                //List<Domain.ProduktKategori> kateIdn = getKategoriID(produktObject);

                //uppdateraProdukt.produkt = produktObject.produkt;
                //uppdateraProdukt.produktGruppID = produktObject.produktGruppID;
                //uppdateraProdukt.produktKategoriID = produktObject.produktKategoriID;
                //uppdateraProdukt.avdelningsnamn = produktObject.avdelningsnamn;
                //uppdateraProdukt.signatur = produktObject.signatur;
                //uppdateraProdukt.andratDatum = produktObject.andratDatum;

                uppdateraProdukt = produktObject;

                database.SubmitChanges();
                return true;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return false;
            }
        }

        //returnerar alla produkter med produktgrupp och produktkategori
        public IEnumerable<Produktregister> getFiltreringskriterier()
        {
            try
            {
                database = new LinqToSQLDataContext(pass);

                IEnumerable<Produktregister> produkter = from Produktregister in database.Produktregisters
                                                         join Produktgrupp in database.Produktgrupps on Produktregister.produktGruppID equals Produktgrupp.produktGruppID
                                                         join Produktkategori in database.Produktkategoris on Produktregister.produktKategoriID equals Produktkategori.produktKategoriID
                                                         select Produktregister;
                //select new { Produktregister.produktID, Produktregister.produkt, Produktgrupp.produktGruppNamn, Produktgrupp.produktGruppID, 
                //    Produktkategori.produktKategoriNamn, Produktregister.avdelningsnamn, Produktregister.andratDatum, Produktregister.signatur };

                //List<Produkt> prodlista = produkter.AsEnumerable()
                //              .Select(p => new Produkt
                //              {
                //                  ProduktID = p.produktID.TrimEnd(),
                //                  ProduktNamn = p.produkt.TrimEnd(),
                //                  ProduktGrupp = p.produktGruppNamn.TrimEnd(),
                //                  ProduktGruppID = p.produktGruppID.TrimEnd(),
                //                  ProduktKategori = p.produktKategoriNamn.TrimEnd(),
                //                  Produktionsomrade = p.avdelningsnamn.TrimEnd(),
                //              }).ToList();

                database.Connection.Close();
                return produkter;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return null;
            }
        }

        //returnerar list på produkter som innehåller inparametrarnas strängar
        public List<Produkt> GetProdukt(string prodOmrade, string prodKateg, string prodGrupp, string prodNamn, string prodId)
        {
            try
            {
                database = new LinqToSQLDataContext(pass);

                var produkter = from Produkt in database.Produktregisters
                                join Produktgrupp in database.Produktgrupps on Produkt.produktGruppID equals Produktgrupp.produktGruppID
                                join Produktkategori in database.Produktkategoris on Produkt.produktKategoriID equals Produktkategori.produktKategoriID

                                where (Produkt.avdelningsnamn.Contains(prodOmrade) &&
                                (Produktkategori.produktKategoriNamn.Contains(prodKateg) &&
                                (Produktgrupp.produktGruppNamn.StartsWith(prodGrupp) && Produktgrupp.produktGruppNamn.EndsWith("") &&
                                (Produkt.produkt.Contains(prodNamn) &&
                                (Produkt.produktID.Contains(prodId))))))
                                select new { Produkt.produktID, Produkt.produkt, Produktgrupp.produktGruppNamn, Produktkategori.produktKategoriNamn, Produkt.avdelningsnamn, Produkt.andratDatum, Produkt.signatur };

                List<Produkt> prodList = produkter.AsEnumerable()
                    .Select(p => new Produkt
                    {
                        ProduktID = p.produktID,
                        ProduktNamn = p.produkt,
                        ProduktGrupp = p.produktGruppNamn,
                        ProduktKategori = p.produktKategoriNamn,
                        Produktionsomrade = p.avdelningsnamn,
                        Datum = (DateTime)p.andratDatum,
                        Signerad = p.signatur
                    }).ToList();

                database.Connection.Close();
                return prodList;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return null;
            }
        }

        //Returnerar produktgrupp efter vilket filterWord som skickas in
        public object GetProductGroup(string filterWord)
        {
            try
            {
                database = new LinqToSQLDataContext(pass);

                var pg = from Produktgrupp in database.Produktgrupps
                         where Produktgrupp.produktGruppNamn.Contains(filterWord)
                         select Produktgrupp;

                database.Connection.Close();
                return pg;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return null;
            }
        }

        //Returnerar alla produkategorier
        public List<Produktkategori> GetProduktkateogori()
        {
            try
            {
                database = new LinqToSQLDataContext(pass);

                var produktKategorier = from Produktkategori in database.Produktkategoris
                                        select Produktkategori;

                List<Produktkategori> produktKategoriLista = produktKategorier.AsEnumerable()
                                .Select(a => new Produktkategori
                                {
                                    produktKategoriID = a.produktKategoriID,
                                    produktKategoriNamn = a.produktKategoriNamn
                                }).ToList();

                database.Connection.Close();
                return produktKategoriLista;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return null;
            }
        }

        //returnerar produktgrupper med produktgruppsID
        public IEnumerable<Produktgrupp> GetQueryGroupIDProd()
        {
            try
            {
                database = new LinqToSQLDataContext(pass);
                IEnumerable<Produktgrupp> produktGrupper = from Produktgrupp in database.Produktgrupps
                                                           select Produktgrupp;

                //List<Produktgrupp> produktGruppLista = produktGrupper.AsEnumerable()
                //                .Select(a => new Produktgrupp
                //                {
                //                    produktGruppID = a.produktGruppID,
                //                    produktGruppNamn = a.produktGruppNamn
                //                }).ToList();

                database.Connection.Close();
                return produktGrupper;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return null;
            }
        }

        //Returnerar produktkategorier med produkategoriID
        public List<Produktkategori> GetQueryKatIDProd()
        {
            try
            {
                database = new LinqToSQLDataContext(pass);

                var produktKategorier = from Produktkategori in database.Produktkategoris
                                        select Produktkategori;

                List<Produktkategori> produktKategoriLista = produktKategorier.AsEnumerable()
                                .Select(a => new Produktkategori
                                {
                                    produktKategoriID = a.produktKategoriID,
                                    produktKategoriNamn = a.produktKategoriNamn
                                }).ToList();

                database.Connection.Close();
                return produktKategoriLista;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return null;
            }
        }

        //Skapar en ny produktgrupp i databasen
        public bool NewProduktGrupp(ProduktGrupp newProdGrupp)
        {
            bool successfull = false;
            database = new LinqToSQLDataContext(pass);
            try
            {
                Produktgrupp nyProduktGrupp = new Produktgrupp
                {
                    produktGruppID = newProdGrupp.ProduktgruppID,
                    produktGruppNamn = newProdGrupp.Produktgruppnamn,
                    andratDatum = newProdGrupp.Datum,
                    signatur = newProdGrupp.Signatur
                };

                database.Produktgrupps.InsertOnSubmit(nyProduktGrupp);
                database.SubmitChanges();

                database.Connection.Close();
                successfull = true;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return false;
            }
            return successfull;
        }

        //Skapar en ny produktkategori
        public bool NewProduktKategori(Produktkategori newProduktKategori)
        {
            bool successfull = false;
            database = new LinqToSQLDataContext(pass);

            try
            {
                Produktkategori nyProduktKategori = new Produktkategori
                {
                    produktKategoriNamn = newProduktKategori.produktKategoriNamn,
                    andratDatum = newProduktKategori.andratDatum,
                    signatur = newProduktKategori.signatur
                };

                database.Produktkategoris.InsertOnSubmit(nyProduktKategori);
                database.SubmitChanges();

                database.Connection.Close();
                successfull = true;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return false;
            }
            return successfull;
        }


        //Check om produkt/produktID Existerar + för intäktsbudgetering för kund
        public bool ValidateIfProductExists(string prodID, string prodNamn)
        {
            try
            {
                database = new LinqToSQLDataContext(pass);

                if (database.Produktregisters.Any(p => p.produktID == prodID && p.produkt == prodNamn))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return false;
            }
        }

        //Returnerar en lista på intäktsbudgeteringar efter valda Inparametrar
        public List<Intäktsbudget> RetrieveFilteredCustomers(string prodID, string prodNamn, string gradA, string gradT)
        {
            try
            {
                database = new LinqToSQLDataContext(pass);

                var budgets = from Intäktsbudgetregisters in database.Intäktsbudgetregisters
                              join Produkt in database.Produktregisters on Intäktsbudgetregisters.produktID equals Produkt.produktID
                              join Kund in database.Kundregisters on Intäktsbudgetregisters.kundID equals Kund.kundID
                              where Intäktsbudgetregisters.produktID == prodID && Produkt.produkt == prodNamn
                              && Intäktsbudgetregisters.gradA.StartsWith(gradA) && Intäktsbudgetregisters.gradT.StartsWith(gradT)
                              select Intäktsbudgetregisters;

                List<Intäktsbudget> intaktsBudgets = new List<Intäktsbudget>();
                foreach (Intäktsbudgetregister iB in budgets)
                {
                    Intäktsbudget nyIB = new Intäktsbudget();
                    nyIB.IntäktsbudgetID = iB.intBudID;
                    nyIB.ProdID = iB.produktID;
                    nyIB.ProduktNamn = iB.Produktregister.produkt;
                    nyIB.Avtal = iB.avtal;
                    nyIB.GradAvtal = iB.gradA;
                    nyIB.Tillägg = iB.tillagg;
                    nyIB.GradTillägg = iB.gradT;
                    nyIB.Kommentar = iB.kommentar;
                    nyIB.KundID = iB.kundID;
                    nyIB.KundNamn = iB.Kundregister.kundNamn;
                    nyIB.Timmar = iB.tim;
                    nyIB.Låst = iB.låst;
                    nyIB.Datum = iB.andratDatum;
                    nyIB.Signatur = iB.signatur;
                    intaktsBudgets.Add(nyIB);
                }
                database.Connection.Close();
                return intaktsBudgets.ToList();

            }
            catch (Exception e)
            {
                database.Connection.Close();
                return null;
            }
        }

        //Returnerar alla produkter inklusive intäktsbudget
        public IEnumerable<Produktregister> RetrieveProductsOnBudget()
        {
            try
            {
                database = new LinqToSQLDataContext(pass);
                //IEnumerable<Produktregister> ProductList = new List<Produktreg>();

                IEnumerable<Produktregister> products = from Produktregister in database.Produktregisters
                                                        join Intäktsbudget in database.Intäktsbudgetregisters on Produktregister.produktID equals Intäktsbudget.produktID
                                                        select Produktregister;

                //foreach (Produktregister pR in products)
                //{
                //    Produkt prod = new Produkt();
                //    prod.ProduktID = pR.produktID;
                //    prod.ProduktNamn = pR.produkt;
                //    prod.ProduktGrupp = pR.Produktgrupp.produktGruppNamn;
                //    prod.ProduktKategori = pR.Produktkategori.produktKategoriNamn;
                //    prod.Produktionsomrade = pR.avdelningsnamn;
                //    ProductList.Add(prod);
                //}

                return products;
            }
            catch (Exception e)
            {
                database.Connection.Close();
                return null;
            }
        }

        //Returnerarr alla produktallokeringar som stämmer överens med ProdID
        public List<ResursAllokeringar> RetrieveProductAllo(string prodID)
        {
            database = new LinqToSQLDataContext(pass);
            List<ResursAllokeringar> listProductAllokering = new List<ResursAllokeringar>();

            try
            {
                var productAllokering = from Produktallokering in database.Produktallokerings
                                        where Produktallokering.produktID.Contains(prodID)
                                        select Produktallokering;

                foreach (Produktallokering pA in productAllokering)
                {
                    ResursAllokeringar prodAllok = new ResursAllokeringar();

                    prodAllok.ProduktID = pA.produktID;
                    prodAllok.PersNr = pA.personnummer;
                    prodAllok.ProcentSats = (int)pA.procentsats;
                    prodAllok.Låst = (bool)pA.låst;
                    prodAllok.ÄndratDatum = (DateTime)pA.ändratDatum;

                    listProductAllokering.Add(prodAllok);
                }
            }
            catch (SqlException SE)
            {
                database.Connection.Close();
                return null;
            }

            return listProductAllokering;
        }
    }
}
